﻿#region File and License Information
/*
<File>
	<Copyright>Copyright © 2007, Daniel Vaughan. All rights reserved.</Copyright>
	<License see="prj:///Documentation/License.txt"/>
	<Owner Name="Daniel Vaughan" Email="dbvaughan@gmail.com"/>
	<CreationDate>2009-04-11 21:46:18Z</CreationDate>
	<LastSubmissionDate>$Date: $</LastSubmissionDate>
	<Version>$Revision: $</Version>
</File>
*/
#endregion

using System.Collections.Generic;
using System.Linq;

using DanielVaughan.IO;
using DanielVaughan.Resources;

namespace DanielVaughan.Services.Implementation
{
	/* TODO: [DV] Comment. */
	public class CommandLineMessageService : MessageService
	{
		readonly ICommandLine commandLine;

		public CommandLineMessageService(ICommandLine commandLine)
		{
			ArgumentValidator.AssertNotNull(commandLine, "commandLine");
			this.commandLine = commandLine;
		}

		public override MessageResult ShowCustomDialog(string message, string caption,
			MessageButton messageButton, MessageImage messageImage, MessageImportance? importanceThreshold, string details)
		{
			/* If the importance threshold has been specified and it's less than the minimum level required (the filter level) 
			 * then we don't show the message. */
			if (importanceThreshold.HasValue && importanceThreshold.Value < MinumumImportance)
			{
				return MessageResult.OK;
			}

			MessageResult result = MessageResult.OK; /* Satisfy compiler with default value. */

			lock (commandLine.SyncLock)
			{
				if (!string.IsNullOrEmpty(caption))
				{
					commandLine.WriteLine(new CommandLineText(caption, CommandLineStyle.Title));
				}

				commandLine.WriteLine(new CommandLineText(message, CommandLineStyle.Normal));
				

				List<KeyValuePair<int, string>> menuOptions;
				int selectedOption;

				switch (messageButton)
				{
					/* TODO: add view details option. */

					case MessageButton.OKCancel:
						menuOptions = new List<KeyValuePair<int, string>>
						              	{
						              		new KeyValuePair<int, string>(1, "Ok"),
						              		new KeyValuePair<int, string>(2, "Cancel")
						              	};
						selectedOption = GetSelectedOption(menuOptions);
						result = selectedOption == 1 ? MessageResult.OK : MessageResult.Cancel;
						break;
					case MessageButton.YesNo:
						menuOptions = new List<KeyValuePair<int, string>>
						              	{
						              		new KeyValuePair<int, string>(1, "Yes"),
						              		new KeyValuePair<int, string>(2, "No")
						              	};
						selectedOption = GetSelectedOption(menuOptions);
						result = selectedOption == 1 ? MessageResult.Yes : MessageResult.No;
						break;
					case MessageButton.YesNoCancel:
						menuOptions = new List<KeyValuePair<int, string>>
						              	{
						              		new KeyValuePair<int, string>(1, "Yes"),
						              		new KeyValuePair<int, string>(2, "No"),
						              		new KeyValuePair<int, string>(3, "Cancel")
						              	};
						selectedOption = GetSelectedOption(menuOptions);
						switch (selectedOption)
						{
							case 1:
								result = MessageResult.Yes;
								break;
							case 2:
								result = MessageResult.No;
								break;
							default:
								result = MessageResult.Cancel;
								break;
						}
						break;
					case MessageButton.OK:
						result = MessageResult.OK;
						break;
				}
			}

			return result;
		}

		int GetSelectedOption(List<KeyValuePair<int, string>> menuOptions)
		{
			var validValues = (from menuOption in menuOptions select menuOption.Key).ToList();
			do
			{
				foreach (var menuItem in menuOptions)
				{
					string menuLine = string.Format(StringResources.Services_ConsoleMessageService_MenuItemFormat,
						menuItem.Key, menuItem.Value);
					commandLine.WriteLine(new CommandLineText(menuLine, CommandLineStyle.MenuItem));
				}
				string line = commandLine.ReadLine();
				if (line != null)
				{
					int result;
					if (int.TryParse(line, out result))
					{
						if (validValues.Contains(result))
						{
							return result;
						}
					}
				}
				commandLine.WriteLine(new CommandLineText("Invalid input.", CommandLineStyle.Error)); /* TODO: Make localizable resource. */
			} while (true);
		}
	}
}
